/********************************************************************************
TITLE:                      	Formatted Output
FILENAME:                   	T_List.cpp
PREPARED FOR:               	CS215 Section CS13-02
PROGRAMMER(S):              	Eric (Fox) Crowell, (Tim, add full name here)
DEVELOPMENT DATE:           	< 12/15/13 >
COMPILER USED:      			Microsoft Visual Studio Professional 2013
- Version 12.0.21005.1 REL
TARGET PLATFORM:         	    Windows 8 x64
================================================================================
REVISION HISTORY

DATE         PROGRAMMER          DESCRIPTION OF CHANGES MADE
------------------------------------------------------------------------------
<12/15/13       Tim                 CPP File created.                        >
<12/16/13       Fox                 Replaced with Lab3 vector class code     >
*******************************************************************************/

#include <math.h>
#include "vector.h"

// ========================================
// CONSTRUCTORS
// ----------------------------------------
// Default Constructor (initializes with hard-coded values). [Fox]
Vector::Vector(){
	this->x = 0.0;
	this->y = 0.0;
	this->z = 0.0;
}

// A constructor that takes arguments for the vector x, y and, z values. [Fox]
Vector::Vector(double x, double y, double z){
	// Take only positive values.
	this->x = x;
	this->y = y;
	this->z = z;
}
// = End of: CONSTRUCTORS =================

// ========================================
// METHODS
// ----------------------------------------
// "x" data member setter [Fox]
void Vector::setX(double value){
	this->x = (value >= 0) ? value : 0;
}

// "y" data member setter [Fox]
void Vector::setY(double value){
	this->y = (value >= 0) ? value : 0;
}
// "z" data member setter [Fox]
void Vector::setZ(double value){
	this->z = (value >= 0) ? value : 0;
}

// get "x" data member [Fox]
double Vector::getX() const{
	return(x);
}

// get "y" data member [Fox]
double Vector::getY() const{
	return(y);
}

// get "z" data member [Fox]
double Vector::getZ() const{
	return(z);
}

// Returns the magnitude of this vector [Fox]
double Vector::magnitude() const{
	double rtnVal = sqrt(x*x + y*y + z*z);
	return(rtnVal);
}
// = End of: METHODS ======================

// ========================================
// OVERLOADED OPERATORS
// ----------------------------------------

// Vector Dot Product 
// double = Vector * Vector [Fox]
double Vector::operator*(const Vector &v) const{
	double product =
		(x * v.x) +
		(y * v.y) +
		(z * v.z);

	return(product);
}

// Scalar Multiplication 1
// Vector = Vector * double [Fox]
Vector Vector::operator*(const double &s) const{
	Vector product(
		(x * s),
		(y * s),
		(z * s)
		);

	return(product);
}

// Scalar Multiplication 2
// Vector = double * Vector [Fox]
Vector operator*(const double &s, const Vector &v){
	Vector product(
		(v.x * s),
		(v.y * s),
		(v.z * s)
		);

	return(product);
}

// Vector Addition
// Vector = Vector + Vector [Fox]
Vector Vector::operator+(const Vector &v) const{
	Vector sum(
		(x + v.x),
		(y + v.y),
		(z + v.z)
		);

	return(sum);
}

// Scalar Addition 1
// Vector = Vector + double [Fox]
Vector Vector::operator+(const double &s) const{
	Vector sum(
		(x + s),
		(y + s),
		(z + s)
		);

	return(sum);
}

// Scalar Addition 2
// Vector = double + Vector [Fox]
Vector operator+(const double &s, const Vector &v){
	Vector sum(
		(v.x + s),
		(v.y + s),
		(v.z + s)
		);

	return(sum);
}

// Vector Subtraction
// Vector = Vector - Vector [Fox]
Vector Vector::operator-(const Vector &v) const{
	Vector dif(
		(x - v.x),
		(y - v.y),
		(z - v.z)
		);

	return(dif);
}

// Scalar Subtraction 1
// Vector = Vector - double [Fox]
Vector Vector::operator-(const double &s) const{
	Vector dif(
		(x - s),
		(y - s),
		(z - s)
		);

	return(dif);
}

// Scalar Subtraction 2
// Vector = double - Vector [Fox]
Vector operator-(const double &s, const Vector &v){
	Vector dif(
		(v.x - s),
		(v.y - s),
		(v.z - s)
		);

	return(dif);
}

/* Negation */
// Vector = -Vector [Fox]
Vector & Vector::operator-(){
	x = -x;
	y = -y;
	z = -z;

	return(*this);
}

// Scalar Division
// Vector = Vector / double [Fox]
Vector Vector::operator/(const double &s) const{
	if (s == 0){ return(*this); } // Ensure we don't divide by 0;
	Vector quo(
		(x / s),
		(y / s),
		(z / s)
		);

	return(quo);
}

/* --- Cross Product --- */
// Vector = Vector / double [Fox]
Vector Vector::operator^(const Vector &v) const{

	Vector cprod(
		(y * v.z - z * v.y),
		(z * v.x - x * v.z),
		(x * v.y - y * v.x)
		);

	return(cprod);
}

/* --- Equality --- */
// bool = Vector == Vector [Fox]
bool Vector::operator==(const Vector &v) const{
	return (x == v.x &&  y == v.y && z == v.z);
}

/* --- Less-Than --- */
// bool = Vector == Vector [Fox]
bool Vector::operator<(const Vector &v) const{
	return(magnitude() < v.magnitude());
}

ostream& operator<<(std::ostream &out, const Vector &v){
	out << "[ " << v.x << ", " << v.y << ", " << v.z << " ]";
	return(out);
}

// = End of: OVERLOADED OPERATORS =========